package com.atguigu.product.products.service.impl;

import com.atguigu.product.products.entity.PmsSkuImagesEntity;
import com.atguigu.product.products.entity.PmsSpuInfoDescEntity;
import com.atguigu.product.products.service.*;
import com.atguigu.product.products.vo.respVo.item.SkuItemSaleAttrVo;
import com.atguigu.product.products.vo.respVo.item.SkuItemVo;
import com.atguigu.product.products.vo.respVo.item.SpuItemAttrGroupVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.product.products.dao.PmsSkuInfoDao;
import com.atguigu.product.products.entity.PmsSkuInfoEntity;


@Service("pmsSkuInfoService")
public class PmsSkuInfoServiceImpl extends ServiceImpl<PmsSkuInfoDao, PmsSkuInfoEntity> implements PmsSkuInfoService {


    @Autowired
    private PmsSkuImagesService imagesService;

    @Autowired
    private PmsSpuInfoDescService pmsSpuInfoDescService;

    @Autowired
    private PmsAttrGroupService attrGroupService;

    @Autowired
    private PmsSkuSaleAttrValueService pmsSkuSaleAttrValueService;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PmsSkuInfoEntity> page = this.page(
                new Query<PmsSkuInfoEntity>().getPage(params),
                new QueryWrapper<PmsSkuInfoEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 根据skuid查询对应商品的信息
     *
     * @param skuId
     * @return SkuItemVo
     */
    public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {

        //TODO 使用异步编排的模式优化代码

        SkuItemVo skuItemVo = new SkuItemVo();
        CompletableFuture<PmsSkuInfoEntity> pmsSkuInfoEntityCompletableFuture = CompletableFuture.supplyAsync(() -> {
            //1、sku基本信息的设置
            PmsSkuInfoEntity pmsSkuInfoEntity = this.baseMapper.selectOne(new QueryWrapper<PmsSkuInfoEntity>().eq("sku_id", skuId));
            skuItemVo.setInfo(pmsSkuInfoEntity);
            return pmsSkuInfoEntity;
        }, threadPoolExecutor);


        //2、sku的图片信息的设置
        CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
            List<PmsSkuImagesEntity> pmsSkuImagesEntities = imagesService.getBaseMapper().selectList(new QueryWrapper<PmsSkuImagesEntity>().eq("sku_id", skuId));
            if (pmsSkuImagesEntities != null && pmsSkuImagesEntities.size() > 0) {
                skuItemVo.setImages(pmsSkuImagesEntities);
            }
        }, threadPoolExecutor);


        //3、获取spu的介绍--需要等到一结束之后才可以执行后面的
        CompletableFuture<Void> voidCompletableFuture = pmsSkuInfoEntityCompletableFuture.thenAcceptAsync((res) -> {
            PmsSpuInfoDescEntity spuInfoDescEntity = pmsSpuInfoDescService.getBaseMapper().selectOne(new QueryWrapper<PmsSpuInfoDescEntity>().eq("spu_id", res.getSpuId()));
            if (spuInfoDescEntity != null) {
                skuItemVo.setDesp(spuInfoDescEntity);
            }
        }, threadPoolExecutor);


        //4.获取spu的规格参数信息--格式是分组及其分组下对应的属性名和属性值
        CompletableFuture<Void> thenAcceptAsync = pmsSkuInfoEntityCompletableFuture.thenAcceptAsync((res) -> {
            List<SpuItemAttrGroupVo> attrGroupVos = attrGroupService.queryGroupWithAttrs(res.getSpuId(), res.getCatalogId());
            skuItemVo.setGroupAttrs(attrGroupVos);
        }, threadPoolExecutor);


        //5.获取spu的规格参数信息--根据spuId获取对应的销售属性的值以及对应的skuID的值
        CompletableFuture<Void> acceptAsync = pmsSkuInfoEntityCompletableFuture.thenAcceptAsync((res) -> {
            List<SkuItemSaleAttrVo> skuItemSaleAttrVos = pmsSkuSaleAttrValueService.querySaleWithAttrs(res.getSpuId());
            skuItemVo.setSaleAttr(skuItemSaleAttrVos);
        }, threadPoolExecutor);

        //等待都执行完成之后返回前端
        CompletableFuture<Void> allOf = CompletableFuture.allOf(completableFuture, acceptAsync, thenAcceptAsync, voidCompletableFuture);

        //添加阻塞等待都执行完毕
        allOf.get();
        return skuItemVo;
    }

}